/**
 *	Xenon Main
 *
 *	Theme by: www.laborator.co
 **/

var public_vars = public_vars || {};

;
(function($, window, undefined) {

    "use strict";

    $(document).ready(function() {
        // Main Vars
        public_vars.$body = $("body");
        public_vars.$pageContainer = public_vars.$body.find(".page-container");
        public_vars.$chat = public_vars.$pageContainer.find("#chat");
        public_vars.$sidebarMenu = public_vars.$pageContainer.find('.sidebar-menu');
        public_vars.$mainMenu = public_vars.$sidebarMenu.find('.main-menu');

        public_vars.$horizontalNavbar = public_vars.$body.find('.navbar.horizontal-menu');
        public_vars.$horizontalMenu = public_vars.$horizontalNavbar.find('.navbar-nav');

        public_vars.$mainContent = public_vars.$pageContainer.find('.main-content');
        public_vars.$mainFooter = public_vars.$body.find('footer.main-footer');

        public_vars.$userInfoMenuHor = public_vars.$body.find('.navbar.horizontal-menu');
        public_vars.$userInfoMenu = public_vars.$body.find('nav.navbar.user-info-navbar');

        public_vars.$settingsPane = public_vars.$body.find('.settings-pane');
        public_vars.$settingsPaneIn = public_vars.$settingsPane.find('.settings-pane-inner');

        public_vars.wheelPropagation = true; // used in Main menu (sidebar)

        public_vars.$pageLoadingOverlay = public_vars.$body.find('.page-loading-overlay');

        public_vars.defaultColorsPalette = ['#68b828', '#7c38bc', '#0e62c7', '#fcd036', '#4fcdfc', '#00b19d', '#ff6264', '#f7aa47'];



        // Page Loading Overlay
        if (public_vars.$pageLoadingOverlay.length) {
            $(window).on('load', function() {
                public_vars.$pageLoadingOverlay.addClass('loaded');
            });
        }

        window.onerror = function() {
            // failsafe remove loading overlay
            public_vars.$pageLoadingOverlay.addClass('loaded');
        }


        // Setup Sidebar Menu
        setup_sidebar_menu();


        // Setup Horizontal Menu
        setup_horizontal_menu();


        // Sticky Footer
        if (public_vars.$mainFooter.hasClass('sticky')) {
            stickFooterToBottom();
            $(window).on('xenon.resized', stickFooterToBottom);
        }


        // Perfect Scrollbar
        if ($.isFunction($.fn.perfectScrollbar)) {
            if (public_vars.$sidebarMenu.hasClass('fixed'))
                ps_init();

            $(".ps-scrollbar").each(function(i, el) {
                var $el = $(el);

                $el.perfectScrollbar({
                    wheelPropagation: false
                });
            });


            // Chat Scrollbar
            var $chat_inner = public_vars.$pageContainer.find('#chat .chat-inner');

            if ($chat_inner.parent().hasClass('fixed'))
                $chat_inner.css({ maxHeight: $(window).height() }).perfectScrollbar();


            // User info opening dropdown trigger PS update
            $(".user-info-navbar .dropdown:has(.ps-scrollbar)").each(function(i, el) {
                var $scrollbar = $(this).find('.ps-scrollbar');

                $(this).on('click', '[data-toggle="dropdown"]', function(ev) {
                    ev.preventDefault();

                    setTimeout(function() {
                        $scrollbar.perfectScrollbar('update');
                    }, 1);
                });
            });


            // Scrollable
            $("div.scrollable").each(function(i, el) {
                var $this = $(el),
                    max_height = parseInt(attrDefault($this, 'max-height', 200), 10);

                max_height = max_height < 0 ? 200 : max_height;

                $this.css({ maxHeight: max_height }).perfectScrollbar({
                    wheelPropagation: true
                });
            });
        }


        // User info search button
        var $uim_search_form = $(".user-info-menu .search-form, .nav.navbar-right .search-form");

        $uim_search_form.each(function(i, el) {
            var $uim_search_input = $(el).find('.form-control');

            $(el).on('click', '.btn', function(ev) {
                if ($uim_search_input.val().trim().length == 0) {
                    jQuery(el).addClass('focused');
                    setTimeout(function() { $uim_search_input.focus(); }, 100);
                    return false;
                }
            });

            $uim_search_input.on('blur', function() {
                jQuery(el).removeClass('focused');
            });
        });



        // Fixed Footer
        if (public_vars.$mainFooter.hasClass('fixed')) {
            public_vars.$mainContent.css({
                paddingBottom: public_vars.$mainFooter.outerHeight(true)
            });
        }



        // Go to to links
        $('body').on('click', 'a[rel="go-top"]', function(ev) {
            ev.preventDefault();

            var obj = { pos: $(window).scrollTop() };

            TweenLite.to(obj, .3, {
                pos: 0,
                ease: Power4.easeOut,
                onUpdate: function() {
                    $(window).scrollTop(obj.pos);
                }
            });
        });




        // User info navbar equal heights
        if (public_vars.$userInfoMenu.length) {
            public_vars.$userInfoMenu.find('.user-info-menu > li').css({
                minHeight: public_vars.$userInfoMenu.outerHeight() - 1
            });
        }



        // Autosize
        if ($.isFunction($.fn.autosize)) {
            $(".autosize, .autogrow").autosize();
        }


        // Custom Checkboxes & radios
        cbr_replace();



        // Auto hidden breadcrumbs
        $(".breadcrumb.auto-hidden").each(function(i, el) {
            var $bc = $(el),
                $as = $bc.find('li a'),
                collapsed_width = $as.width(),
                expanded_width = 0;

            $as.each(function(i, el) {
                var $a = $(el);

                expanded_width = $a.outerWidth(true);
                $a.addClass('collapsed').width(expanded_width);

                $a.hover(function() {
                        $a.removeClass('collapsed');
                    },
                    function() {
                        $a.addClass('collapsed');
                    });
            });
        });



        // Close Modal on Escape Keydown
        $(window).on('keydown', function(ev) {
            // Escape
            if (ev.keyCode == 27) {
                // Close opened modal
                if (public_vars.$body.hasClass('modal-open'))
                    $(".modal-open .modal:visible").modal('hide');
            }
        });


        // Minimal Addon focus interaction
        $(".input-group.input-group-minimal:has(.form-control)").each(function(i, el) {
            var $this = $(el),
                $fc = $this.find('.form-control');

            $fc.on('focus', function() {
                $this.addClass('focused');
            }).on('blur', function() {
                $this.removeClass('focused');
            });
        });



        // Spinner
        $(".input-group.spinner").each(function(i, el) {
            var $ig = $(el),
                $dec = $ig.find('[data-type="decrement"]'),
                $inc = $ig.find('[data-type="increment"]'),
                $inp = $ig.find('.form-control'),

                step = attrDefault($ig, 'step', 1),
                min = attrDefault($ig, 'min', 0),
                max = attrDefault($ig, 'max', 0),
                umm = min < max;


            $dec.on('click', function(ev) {
                ev.preventDefault();

                var num = new Number($inp.val()) - step;

                if (umm && num <= min) {
                    num = min;
                }

                $inp.val(num);
            });

            $inc.on('click', function(ev) {
                ev.preventDefault();

                var num = new Number($inp.val()) + step;

                if (umm && num >= max) {
                    num = max;
                }

                $inp.val(num);
            });
        });




        // Select2 Dropdown replacement
        if ($.isFunction($.fn.select2)) {
            $(".select2").each(function(i, el) {
                var $this = $(el),
                    opts = {
                        allowClear: attrDefault($this, 'allowClear', false)
                    };

                $this.select2(opts);
                $this.addClass('visible');

                //$this.select2("open");
            });


            if ($.isFunction($.fn.niceScroll)) {
                $(".select2-results").niceScroll({
                    cursorcolor: '#d4d4d4',
                    cursorborder: '1px solid #ccc',
                    railpadding: { right: 3 }
                });
            }
        }




        // SelectBoxIt Dropdown replacement
        if ($.isFunction($.fn.selectBoxIt)) {
            $("select.selectboxit").each(function(i, el) {
                var $this = $(el),
                    opts = {
                        showFirstOption: attrDefault($this, 'first-option', true),
                        'native': attrDefault($this, 'native', false),
                        defaultText: attrDefault($this, 'text', ''),
                    };

                $this.addClass('visible');
                $this.selectBoxIt(opts);
            });
        }



        // Datepicker
        if ($.isFunction($.fn.datepicker)) {
            $(".datepicker").each(function(i, el) {
                var $this = $(el),
                    opts = {
                        format: attrDefault($this, 'format', 'mm/dd/yyyy'),
                        startDate: attrDefault($this, 'startDate', ''),
                        endDate: attrDefault($this, 'endDate', ''),
                        daysOfWeekDisabled: attrDefault($this, 'disabledDays', ''),
                        startView: attrDefault($this, 'startView', 0),
                        rtl: rtl()
                    },
                    $n = $this.next(),
                    $p = $this.prev();

                $this.datepicker(opts);

                if ($n.is('.input-group-addon') && $n.has('a')) {
                    $n.on('click', function(ev) {
                        ev.preventDefault();

                        $this.datepicker('show');
                    });
                }

                if ($p.is('.input-group-addon') && $p.has('a')) {
                    $p.on('click', function(ev) {
                        ev.preventDefault();

                        $this.datepicker('show');
                    });
                }
            });
        }



        // Date Range Picker
        if ($.isFunction($.fn.daterangepicker)) {
            $(".daterange").each(function(i, el) {
                // Change the range as you desire
                var ranges = {
                    'Today': [moment(), moment()],
                    'Yesterday': [moment().subtract('days', 1), moment().subtract('days', 1)],
                    'Last 7 Days': [moment().subtract('days', 6), moment()],
                    'Last 30 Days': [moment().subtract('days', 29), moment()],
                    'This Month': [moment().startOf('month'), moment().endOf('month')],
                    'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')]
                };

                var $this = $(el),
                    opts = {
                        format: attrDefault($this, 'format', 'MM/DD/YYYY'),
                        timePicker: attrDefault($this, 'timePicker', false),
                        timePickerIncrement: attrDefault($this, 'timePickerIncrement', false),
                        separator: attrDefault($this, 'separator', ' - '),
                    },
                    min_date = attrDefault($this, 'minDate', ''),
                    max_date = attrDefault($this, 'maxDate', ''),
                    start_date = attrDefault($this, 'startDate', ''),
                    end_date = attrDefault($this, 'endDate', '');

                if ($this.hasClass('add-ranges')) {
                    opts['ranges'] = ranges;
                }

                if (min_date.length) {
                    opts['minDate'] = min_date;
                }

                if (max_date.length) {
                    opts['maxDate'] = max_date;
                }

                if (start_date.length) {
                    opts['startDate'] = start_date;
                }

                if (end_date.length) {
                    opts['endDate'] = end_date;
                }


                $this.daterangepicker(opts, function(start, end) {
                    var drp = $this.data('daterangepicker');

                    if ($this.is('[data-callback]')) {
                        //daterange_callback(start, end);
                        callback_test(start, end);
                    }

                    if ($this.hasClass('daterange-inline')) {
                        $this.find('span').html(start.format(drp.format) + drp.separator + end.format(drp.format));
                    }
                });

                if (typeof opts['ranges'] == 'object') {
                    $this.data('daterangepicker').container.removeClass('show-calendar');
                }
            });
        }



        // Timepicker
        if ($.isFunction($.fn.timepicker)) {
            $(".timepicker").each(function(i, el) {
                var $this = $(el),
                    opts = {
                        template: attrDefault($this, 'template', false),
                        showSeconds: attrDefault($this, 'showSeconds', false),
                        defaultTime: attrDefault($this, 'defaultTime', 'current'),
                        showMeridian: attrDefault($this, 'showMeridian', true),
                        minuteStep: attrDefault($this, 'minuteStep', 15),
                        secondStep: attrDefault($this, 'secondStep', 15)
                    },
                    $n = $this.next(),
                    $p = $this.prev();

                $this.timepicker(opts);

                if ($n.is('.input-group-addon') && $n.has('a')) {
                    $n.on('click', function(ev) {
                        ev.preventDefault();

                        $this.timepicker('showWidget');
                    });
                }

                if ($p.is('.input-group-addon') && $p.has('a')) {
                    $p.on('click', function(ev) {
                        ev.preventDefault();

                        $this.timepicker('showWidget');
                    });
                }
            });
        }



        // Colorpicker
        if ($.isFunction($.fn.colorpicker)) {
            $(".colorpicker").each(function(i, el) {
                var $this = $(el),
                    opts = {},
                    $n = $this.next(),
                    $p = $this.prev(),

                    $preview = $this.siblings('.input-group-addon').find('.color-preview');

                $this.colorpicker(opts);

                if ($n.is('.input-group-addon') && $n.has('a')) {
                    $n.on('click', function(ev) {
                        ev.preventDefault();

                        $this.colorpicker('show');
                    });
                }

                if ($p.is('.input-group-addon') && $p.has('a')) {
                    $p.on('click', function(ev) {
                        ev.preventDefault();

                        $this.colorpicker('show');
                    });
                }

                if ($preview.length) {
                    $this.on('changeColor', function(ev) {

                        $preview.css('background-color', ev.color.toHex());
                    });

                    if ($this.val().length) {
                        $preview.css('background-color', $this.val());
                    }
                }
            });
        }




        // Form Validation
        if ($.isFunction($.fn.validate)) {
            $("form.validate").each(function(i, el) {
                var $this = $(el),
                    opts = {
                        rules: {},
                        messages: {},
                        errorElement: 'span',
                        errorClass: 'validate-has-error',
                        highlight: function(element) {
                            $(element).closest('.form-group').addClass('validate-has-error');
                        },
                        unhighlight: function(element) {
                            $(element).closest('.form-group').removeClass('validate-has-error');
                        },
                        errorPlacement: function(error, element) {
                            if (element.closest('.has-switch').length) {
                                error.insertAfter(element.closest('.has-switch'));
                            } else
                            if (element.parent('.checkbox, .radio').length || element.parent('.input-group').length) {
                                error.insertAfter(element.parent());
                            } else {
                                error.insertAfter(element);
                            }
                        }
                    },
                    $fields = $this.find('[data-validate]');


                $fields.each(function(j, el2) {
                    var $field = $(el2),
                        name = $field.attr('name'),
                        validate = attrDefault($field, 'validate', '').toString(),
                        _validate = validate.split(',');

                    for (var k in _validate) {
                        var rule = _validate[k],
                            params,
                            message;

                        if (typeof opts['rules'][name] == 'undefined') {
                            opts['rules'][name] = {};
                            opts['messages'][name] = {};
                        }

                        if ($.inArray(rule, ['required', 'url', 'email', 'number', 'date', 'creditcard']) != -1) {
                            opts['rules'][name][rule] = true;

                            message = $field.data('message-' + rule);

                            if (message) {
                                opts['messages'][name][rule] = message;
                            }
                        }
                        // Parameter Value (#1 parameter)
                        else
                        if (params = rule.match(/(\w+)\[(.*?)\]/i)) {
                            if ($.inArray(params[1], ['min', 'max', 'minlength', 'maxlength', 'equalTo']) != -1) {
                                opts['rules'][name][params[1]] = params[2];


                                message = $field.data('message-' + params[1]);

                                if (message) {
                                    opts['messages'][name][params[1]] = message;
                                }
                            }
                        }
                    }
                });

                $this.validate(opts);
            });
        }




        // Input Mask
        if ($.isFunction($.fn.inputmask)) {
            $("[data-mask]").each(function(i, el) {
                var $this = $(el),
                    mask = $this.data('mask').toString(),
                    opts = {
                        numericInput: attrDefault($this, 'numeric', false),
                        radixPoint: attrDefault($this, 'radixPoint', ''),
                        rightAlign: attrDefault($this, 'numericAlign', 'left') == 'right'
                    },
                    placeholder = attrDefault($this, 'placeholder', ''),
                    is_regex = attrDefault($this, 'isRegex', '');

                if (placeholder.length) {
                    opts[placeholder] = placeholder;
                }

                switch (mask.toLowerCase()) {
                    case "phone":
                        mask = "(999) 999-9999";
                        break;

                    case "currency":
                    case "rcurrency":

                        var sign = attrDefault($this, 'sign', '$');;

                        mask = "999,999,999.99";

                        if ($this.data('mask').toLowerCase() == 'rcurrency') {
                            mask += ' ' + sign;
                        } else {
                            mask = sign + ' ' + mask;
                        }

                        opts.numericInput = true;
                        opts.rightAlignNumerics = false;
                        opts.radixPoint = '.';
                        break;

                    case "email":
                        mask = 'Regex';
                        opts.regex = "[a-zA-Z0-9._%-]+@[a-zA-Z0-9-]+\\.[a-zA-Z]{2,4}";
                        break;

                    case "fdecimal":
                        mask = 'decimal';
                        $.extend(opts, {
                            autoGroup: true,
                            groupSize: 3,
                            radixPoint: attrDefault($this, 'rad', '.'),
                            groupSeparator: attrDefault($this, 'dec', ',')
                        });
                }

                if (is_regex) {
                    opts.regex = mask;
                    mask = 'Regex';
                }

                $this.inputmask(mask, opts);
            });
        }



        // Form Wizard
        if ($.isFunction($.fn.bootstrapWizard)) {
            $(".form-wizard").each(function(i, el) {
                var $this = $(el),
                    $tabs = $this.find('> .tabs > li'),
                    $progress = $this.find(".progress-indicator"),
                    _index = $this.find('> ul > li.active').index();

                // Validation
                var checkFormWizardValidaion = function(tab, navigation, index) {
                    if ($this.hasClass('validate')) {
                        var $valid = $this.valid();

                        if (!$valid) {
                            $this.data('validator').focusInvalid();
                            return false;
                        }
                    }

                    return true;
                };

                // Setup Progress
                if (_index > 0) {
                    $progress.css({ width: _index / $tabs.length * 100 + '%' });
                    $tabs.removeClass('completed').slice(0, _index).addClass('completed');
                }

                $this.bootstrapWizard({
                    tabClass: "",
                    onTabShow: function($tab, $navigation, index) {
                        var pct = $tabs.eq(index).position().left / $tabs.parent().width() * 100;

                        $tabs.removeClass('completed').slice(0, index).addClass('completed');
                        $progress.css({ width: pct + '%' });
                    },

                    onNext: checkFormWizardValidaion,
                    onTabClick: checkFormWizardValidaion
                });

                $this.data('bootstrapWizard').show(_index);

                $this.find('.pager a').on('click', function(ev) {
                    ev.preventDefault();
                });
            });
        }




        // Slider
        if ($.isFunction($.fn.slider)) {
            $(".slider").each(function(i, el) {
                var $this = $(el),
                    $label_1 = $('<span class="ui-label"></span>'),
                    $label_2 = $label_1.clone(),

                    orientation = attrDefault($this, 'vertical', 0) != 0 ? 'vertical' : 'horizontal',

                    prefix = attrDefault($this, 'prefix', ''),
                    postfix = attrDefault($this, 'postfix', ''),

                    fill = attrDefault($this, 'fill', ''),
                    $fill = $(fill),

                    step = attrDefault($this, 'step', 1),
                    value = attrDefault($this, 'value', 5),
                    min = attrDefault($this, 'min', 0),
                    max = attrDefault($this, 'max', 100),
                    min_val = attrDefault($this, 'min-val', 10),
                    max_val = attrDefault($this, 'max-val', 90),

                    is_range = $this.is('[data-min-val]') || $this.is('[data-max-val]'),

                    reps = 0;


                // Range Slider Options
                if (is_range) {
                    $this.slider({
                        range: true,
                        orientation: orientation,
                        min: min,
                        max: max,
                        values: [min_val, max_val],
                        step: step,
                        slide: function(e, ui) {
                            var min_val = (prefix ? prefix : '') + ui.values[0] + (postfix ? postfix : ''),
                                max_val = (prefix ? prefix : '') + ui.values[1] + (postfix ? postfix : '');

                            $label_1.html(min_val);
                            $label_2.html(max_val);

                            if (fill)
                                $fill.val(min_val + ',' + max_val);

                            reps++;
                        },
                        change: function(ev, ui) {
                            if (reps == 1) {
                                var min_val = (prefix ? prefix : '') + ui.values[0] + (postfix ? postfix : ''),
                                    max_val = (prefix ? prefix : '') + ui.values[1] + (postfix ? postfix : '');

                                $label_1.html(min_val);
                                $label_2.html(max_val);

                                if (fill)
                                    $fill.val(min_val + ',' + max_val);
                            }

                            reps = 0;
                        }
                    });

                    var $handles = $this.find('.ui-slider-handle');

                    $label_1.html((prefix ? prefix : '') + min_val + (postfix ? postfix : ''));
                    $handles.first().append($label_1);

                    $label_2.html((prefix ? prefix : '') + max_val + (postfix ? postfix : ''));
                    $handles.last().append($label_2);
                }
                // Normal Slider
                else {

                    $this.slider({
                        range: attrDefault($this, 'basic', 0) ? false : "min",
                        orientation: orientation,
                        min: min,
                        max: max,
                        value: value,
                        step: step,
                        slide: function(ev, ui) {
                            var val = (prefix ? prefix : '') + ui.value + (postfix ? postfix : '');

                            $label_1.html(val);


                            if (fill)
                                $fill.val(val);

                            reps++;
                        },
                        change: function(ev, ui) {
                            if (reps == 1) {
                                var val = (prefix ? prefix : '') + ui.value + (postfix ? postfix : '');

                                $label_1.html(val);

                                if (fill)
                                    $fill.val(val);
                            }

                            reps = 0;
                        }
                    });

                    var $handles = $this.find('.ui-slider-handle');
                    //$fill = $('<div class="ui-fill"></div>');

                    $label_1.html((prefix ? prefix : '') + value + (postfix ? postfix : ''));
                    $handles.html($label_1);

                    //$handles.parent().prepend( $fill );

                    //$fill.width($handles.get(0).style.left);
                }

            })
        }




        // jQuery Knob
        if ($.isFunction($.fn.knob)) {
            $(".knob").knob({
                change: function(value) {},
                release: function(value) {},
                cancel: function() {},
                draw: function() {

                    if (this.$.data('skin') == 'tron') {

                        var a = this.angle(this.cv) // Angle
                            ,
                            sa = this.startAngle // Previous start angle
                            ,
                            sat = this.startAngle // Start angle
                            ,
                            ea // Previous end angle
                            , eat = sat + a // End angle
                            ,
                            r = 1;

                        this.g.lineWidth = this.lineWidth;

                        this.o.cursor && (sat = eat - 0.3) && (eat = eat + 0.3);

                        if (this.o.displayPrevious) {
                            ea = this.startAngle + this.angle(this.v);
                            this.o.cursor && (sa = ea - 0.3) && (ea = ea + 0.3);
                            this.g.beginPath();
                            this.g.strokeStyle = this.pColor;
                            this.g.arc(this.xy, this.xy, this.radius - this.lineWidth, sa, ea, false);
                            this.g.stroke();
                        }

                        this.g.beginPath();
                        this.g.strokeStyle = r ? this.o.fgColor : this.fgColor;
                        this.g.arc(this.xy, this.xy, this.radius - this.lineWidth, sat, eat, false);
                        this.g.stroke();

                        this.g.lineWidth = 2;
                        this.g.beginPath();
                        this.g.strokeStyle = this.o.fgColor;
                        this.g.arc(this.xy, this.xy, this.radius - this.lineWidth + 1 + this.lineWidth * 2 / 3, 0, 2 * Math.PI, false);
                        this.g.stroke();

                        return false;
                    }
                }
            });
        }




        // Wysiwyg Editor
        if ($.isFunction($.fn.wysihtml5)) {
            $(".wysihtml5").each(function(i, el) {
                var $this = $(el),
                    stylesheets = attrDefault($this, 'stylesheet-url', '')

                $(".wysihtml5").wysihtml5({
                    size: 'white',
                    stylesheets: stylesheets.split(','),
                    "html": attrDefault($this, 'html', true),
                    "color": attrDefault($this, 'colors', true),
                });
            });
        }




        // CKeditor WYSIWYG
        if ($.isFunction($.fn.ckeditor)) {
            $(".ckeditor").ckeditor({
                contentsLangDirection: rtl() ? 'rtl' : 'ltr'
            });
        }



        // Dropzone is prezent
        if (typeof Dropzone != 'undefined') {
            Dropzone.autoDiscover = false;

            $(".dropzone[action]").each(function(i, el) {
                $(el).dropzone();
            });
        }




        // Tocify Table
        if ($.isFunction($.fn.tocify) && $("#toc").length) {
            $("#toc").tocify({
                context: '.tocify-content',
                selectors: "h2,h3,h4,h5"
            });


            var $this = $(".tocify"),
                watcher = scrollMonitor.create($this.get(0));

            $this.width($this.parent().width());

            watcher.lock();

            watcher.stateChange(function() {
                $($this.get(0)).toggleClass('fixed', this.isAboveViewport)
            });
        }



        // Login Form Label Focusing
        $(".login-form .form-group:has(label)").each(function(i, el) {
            var $this = $(el),
                $label = $this.find('label'),
                $input = $this.find('.form-control');

            $input.on('focus', function() {
                $this.addClass('is-focused');
            });

            $input.on('keydown', function() {
                $this.addClass('is-focused');
            });

            $input.on('blur', function() {
                $this.removeClass('is-focused');

                if ($input.val().trim().length > 0) {
                    $this.addClass('is-focused');
                }
            });

            $label.on('click', function() {
                $input.focus();
            });

            if ($input.val().trim().length > 0) {
                $this.addClass('is-focused');
            }
        });

    });


    // Enable/Disable Resizable Event
    var wid = 0;

    $(window).resize(function() {
        clearTimeout(wid);
        wid = setTimeout(trigger_resizable, 200);
    });


})(jQuery, window);



// Sideber Menu Setup function
var sm_duration = .2,
    sm_transition_delay = 150;

function setup_sidebar_menu() {
    if (public_vars.$sidebarMenu.length) {
        var $items_with_subs = public_vars.$sidebarMenu.find('li:has(> ul)'),
            toggle_others = public_vars.$sidebarMenu.hasClass('toggle-others');

        $items_with_subs.filter('.active').addClass('expanded');

        $items_with_subs.each(function(i, el) {
            var $li = jQuery(el),
                $a = $li.children('a'),
                $sub = $li.children('ul');

            $li.addClass('has-sub');

            $a.on('click', function(ev) {
                ev.preventDefault();

                if (toggle_others) {
                    sidebar_menu_close_items_siblings($li);
                }

                if ($li.hasClass('expanded') || $li.hasClass('opened'))
                    sidebar_menu_item_collapse($li, $sub);
                else
                    sidebar_menu_item_expand($li, $sub);
            });
        });
    }
}

function sidebar_menu_item_expand($li, $sub) {
    if ($li.data('is-busy') || ($li.parent('.main-menu').length && public_vars.$sidebarMenu.hasClass('collapsed')))
        return;

    $li.addClass('expanded').data('is-busy', true);
    $sub.show();

    var $sub_items = $sub.children(),
        sub_height = $sub.outerHeight(),

        win_y = jQuery(window).height(),
        total_height = $li.outerHeight(),
        current_y = public_vars.$sidebarMenu.scrollTop(),
        item_max_y = $li.position().top + current_y,
        fit_to_viewpport = public_vars.$sidebarMenu.hasClass('fit-in-viewport');

    $sub_items.addClass('is-hidden');
    $sub.height(0);


    TweenMax.to($sub, sm_duration, {
        css: { height: sub_height },
        onUpdate: ps_update,
        onComplete: function() {
            $sub.height('');
        }
    });

    var interval_1 = $li.data('sub_i_1'),
        interval_2 = $li.data('sub_i_2');

    window.clearTimeout(interval_1);

    interval_1 = setTimeout(function() {
        $sub_items.each(function(i, el) {
            var $sub_item = jQuery(el);

            $sub_item.addClass('is-shown');
        });

        var finish_on = sm_transition_delay * $sub_items.length,
            t_duration = parseFloat($sub_items.eq(0).css('transition-duration')),
            t_delay = parseFloat($sub_items.last().css('transition-delay'));

        if (t_duration && t_delay) {
            finish_on = (t_duration + t_delay) * 1000;
        }

        // In the end
        window.clearTimeout(interval_2);

        interval_2 = setTimeout(function() {
            $sub_items.removeClass('is-hidden is-shown');

        }, finish_on);


        $li.data('is-busy', false);

    }, 0);

    $li.data('sub_i_1', interval_1),
        $li.data('sub_i_2', interval_2);
}

function sidebar_menu_item_collapse($li, $sub) {
    if ($li.data('is-busy'))
        return;

    var $sub_items = $sub.children();

    $li.removeClass('expanded').data('is-busy', true);
    $sub_items.addClass('hidden-item');

    TweenMax.to($sub, sm_duration, {
        css: { height: 0 },
        onUpdate: ps_update,
        onComplete: function() {
            $li.data('is-busy', false).removeClass('opened');

            $sub.attr('style', '').hide();
            $sub_items.removeClass('hidden-item');

            $li.find('li.expanded ul').attr('style', '').hide().parent().removeClass('expanded');

            ps_update(true);
        }
    });
}

function sidebar_menu_close_items_siblings($li) {
    $li.siblings().not($li).filter('.expanded, .opened').each(function(i, el) {
        var $_li = jQuery(el),
            $_sub = $_li.children('ul');

        sidebar_menu_item_collapse($_li, $_sub);
    });
}


// Horizontal Menu
function setup_horizontal_menu() {
    if (public_vars.$horizontalMenu.length) {
        var $items_with_subs = public_vars.$horizontalMenu.find('li:has(> ul)'),
            click_to_expand = public_vars.$horizontalMenu.hasClass('click-to-expand');

        if (click_to_expand) {
            public_vars.$mainContent.add(public_vars.$sidebarMenu).on('click', function(ev) {
                $items_with_subs.removeClass('hover');
            });
        }

        $items_with_subs.each(function(i, el) {
            var $li = jQuery(el),
                $a = $li.children('a'),
                $sub = $li.children('ul'),
                is_root_element = $li.parent().is('.navbar-nav');

            $li.addClass('has-sub');

            // Mobile Only
            $a.on('click', function(ev) {
                if (isxs()) {
                    ev.preventDefault();

                    // Automatically will toggle other menu items in mobile view
                    if (true) {
                        sidebar_menu_close_items_siblings($li);
                    }

                    if ($li.hasClass('expanded') || $li.hasClass('opened'))
                        sidebar_menu_item_collapse($li, $sub);
                    else
                        sidebar_menu_item_expand($li, $sub);
                }
            });

            // Click To Expand
            if (click_to_expand) {
                $a.on('click', function(ev) {
                    ev.preventDefault();

                    if (isxs())
                        return;

                    // For parents only
                    if (is_root_element) {
                        $items_with_subs.filter(function(i, el) { return jQuery(el).parent().is('.navbar-nav'); }).not($li).removeClass('hover');
                        $li.toggleClass('hover');
                    }
                    // Sub menus
                    else {
                        var sub_height;

                        // To Expand
                        if ($li.hasClass('expanded') == false) {
                            $li.addClass('expanded');
                            $sub.addClass('is-visible');

                            sub_height = $sub.outerHeight();

                            $sub.height(0);

                            TweenLite.to($sub, .15, { css: { height: sub_height }, ease: Sine.easeInOut, onComplete: function() { $sub.attr('style', ''); } });

                            // Hide Existing in the list
                            $li.siblings().find('> ul.is-visible').not($sub).each(function(i, el) {
                                var $el = jQuery(el);

                                sub_height = $el.outerHeight();

                                $el.removeClass('is-visible').height(sub_height);
                                $el.parent().removeClass('expanded');

                                TweenLite.to($el, .15, { css: { height: 0 }, onComplete: function() { $el.attr('style', ''); } });
                            });
                        }
                        // To Collapse
                        else {
                            sub_height = $sub.outerHeight();

                            $li.removeClass('expanded');
                            $sub.removeClass('is-visible').height(sub_height);
                            TweenLite.to($sub, .15, { css: { height: 0 }, onComplete: function() { $sub.attr('style', ''); } });
                        }
                    }
                });
            }
            // Hover To Expand
            else {
                $li.hoverIntent({
                    over: function() {
                        if (isxs())
                            return;

                        if (is_root_element) {
                            $li.addClass('hover');
                        } else {
                            $sub.addClass('is-visible');
                            sub_height = $sub.outerHeight();

                            $sub.height(0);

                            TweenLite.to($sub, .25, { css: { height: sub_height }, ease: Sine.easeInOut, onComplete: function() { $sub.attr('style', ''); } });
                        }
                    },
                    out: function() {
                        if (isxs())
                            return;

                        if (is_root_element) {
                            $li.removeClass('hover');
                        } else {
                            sub_height = $sub.outerHeight();

                            $li.removeClass('expanded');
                            $sub.removeClass('is-visible').height(sub_height);
                            TweenLite.to($sub, .25, { css: { height: 0 }, onComplete: function() { $sub.attr('style', ''); } });
                        }
                    },
                    timeout: 200,
                    interval: is_root_element ? 10 : 100
                });
            }
        });
    }
}


function stickFooterToBottom() {
    public_vars.$mainFooter.add(public_vars.$mainContent).add(public_vars.$sidebarMenu).attr('style', '');

    if (isxs())
        return false;

    if (public_vars.$mainFooter.hasClass('sticky')) {
        var win_height = jQuery(window).height(),
            footer_height = public_vars.$mainFooter.outerHeight(true),
            main_content_height = public_vars.$mainFooter.position().top + footer_height,
            main_content_height_only = main_content_height - footer_height,
            extra_height = public_vars.$horizontalNavbar.outerHeight();


        if (win_height > main_content_height - parseInt(public_vars.$mainFooter.css('marginTop'), 10)) {
            public_vars.$mainFooter.css({
                marginTop: win_height - main_content_height - extra_height
            });
        }
    }
}


// Perfect scroll bar functions by Arlind Nushi
function ps_update(destroy_init) {
    if (isxs())
        return;

    if (jQuery.isFunction(jQuery.fn.perfectScrollbar)) {
        if (public_vars.$sidebarMenu.hasClass('collapsed')) {
            return;
        }

        public_vars.$sidebarMenu.find('.sidebar-menu-inner').perfectScrollbar('update');

        if (destroy_init) {
            ps_destroy();
            ps_init();
        }
    }
}


function ps_init() {
    if (isxs())
        return;

    if (jQuery.isFunction(jQuery.fn.perfectScrollbar)) {
        if (public_vars.$sidebarMenu.hasClass('collapsed') || !public_vars.$sidebarMenu.hasClass('fixed')) {
            return;
        }

        public_vars.$sidebarMenu.find('.sidebar-menu-inner').perfectScrollbar({
            wheelSpeed: 2,
            wheelPropagation: public_vars.wheelPropagation
        });
    }
}

function ps_destroy() {
    if (jQuery.isFunction(jQuery.fn.perfectScrollbar)) {
        public_vars.$sidebarMenu.find('.sidebar-menu-inner').perfectScrollbar('destroy');
    }
}



// Radio and Check box replacement by Arlind Nushi
function cbr_replace() {
    var $inputs = jQuery('input[type="checkbox"].cbr, input[type="radio"].cbr').filter(':not(.cbr-done)'),
        $wrapper = '<div class="cbr-replaced"><div class="cbr-input"></div><div class="cbr-state"><span></span></div></div>';

    $inputs.each(function(i, el) {
        var $el = jQuery(el),
            is_radio = $el.is(':radio'),
            is_checkbox = $el.is(':checkbox'),
            is_disabled = $el.is(':disabled'),
            styles = ['primary', 'secondary', 'success', 'danger', 'warning', 'info', 'purple', 'blue', 'red', 'gray', 'pink', 'yellow', 'orange', 'turquoise'];

        if (!is_radio && !is_checkbox)
            return;

        $el.after($wrapper);
        $el.addClass('cbr-done');

        var $wrp = $el.next();
        $wrp.find('.cbr-input').append($el);

        if (is_radio)
            $wrp.addClass('cbr-radio');

        if (is_disabled)
            $wrp.addClass('cbr-disabled');

        if ($el.is(':checked')) {
            $wrp.addClass('cbr-checked');
        }


        // Style apply
        jQuery.each(styles, function(key, val) {
            var cbr_class = 'cbr-' + val;

            if ($el.hasClass(cbr_class)) {
                $wrp.addClass(cbr_class);
                $el.removeClass(cbr_class);
            }
        });


        // Events
        $wrp.on('click', function(ev) {
            if (is_radio && $el.prop('checked') || $wrp.parent().is('label'))
                return;

            if (jQuery(ev.target).is($el) == false) {
                $el.prop('checked', !$el.is(':checked'));
                $el.trigger('change');
            }
        });

        $el.on('change', function(ev) {
            $wrp.removeClass('cbr-checked');

            if ($el.is(':checked'))
                $wrp.addClass('cbr-checked');

            cbr_recheck();
        });
    });
}


function cbr_recheck() {
    var $inputs = jQuery("input.cbr-done");

    $inputs.each(function(i, el) {
        var $el = jQuery(el),
            is_radio = $el.is(':radio'),
            is_checkbox = $el.is(':checkbox'),
            is_disabled = $el.is(':disabled'),
            $wrp = $el.closest('.cbr-replaced');

        if (is_disabled)
            $wrp.addClass('cbr-disabled');

        if (is_radio && !$el.prop('checked') && $wrp.hasClass('cbr-checked')) {
            $wrp.removeClass('cbr-checked');
        }
    });
}


// Element Attribute Helper
function attrDefault($el, data_var, default_val) {
    if (typeof $el.data(data_var) != 'undefined') {
        return $el.data(data_var);
    }

    return default_val;
}


// Test function
function callback_test() {
    alert("Callback function executed! No. of arguments: " + arguments.length + "\n\nSee console log for outputed of the arguments.");

    console.log(arguments);
}


// Date Formatter
function date(format, timestamp) {
    //	discuss at: http://phpjs.org/functions/date/
    // original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
    // original by: gettimeofday
    //	parts by: Peter-Paul Koch (http://www.quirksmode.org/js/beat.html)
    // improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // improved by: MeEtc (http://yass.meetcweb.com)
    // improved by: Brad Touesnard
    // improved by: Tim Wiel
    // improved by: Bryan Elliott
    // improved by: David Randall
    // improved by: Theriault
    // improved by: Theriault
    // improved by: Brett Zamir (http://brett-zamir.me)
    // improved by: Theriault
    // improved by: Thomas Beaucourt (http://www.webapp.fr)
    // improved by: JT
    // improved by: Theriault
    // improved by: Rafał Kukawski (http://blog.kukawski.pl)
    // improved by: Theriault
    //	input by: Brett Zamir (http://brett-zamir.me)
    //	input by: majak
    //	input by: Alex
    //	input by: Martin
    //	input by: Alex Wilson
    //	input by: Haravikk
    // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // bugfixed by: majak
    // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // bugfixed by: Brett Zamir (http://brett-zamir.me)
    // bugfixed by: omid (http://phpjs.org/functions/380:380#comment_137122)
    // bugfixed by: Chris (http://www.devotis.nl/)
    //		note: Uses global: php_js to store the default timezone
    //		note: Although the function potentially allows timezone info (see notes), it currently does not set
    //		note: per a timezone specified by date_default_timezone_set(). Implementers might use
    //		note: this.php_js.currentTimezoneOffset and this.php_js.currentTimezoneDST set by that function
    //		note: in order to adjust the dates in this function (or our other date functions!) accordingly
    //	 example 1: date('H:m:s \\m \\i\\s \\m\\o\\n\\t\\h', 1062402400);
    //	 returns 1: '09:09:40 m is month'
    //	 example 2: date('F j, Y, g:i a', 1062462400);
    //	 returns 2: 'September 2, 2003, 2:26 am'
    //	 example 3: date('Y W o', 1062462400);
    //	 returns 3: '2003 36 2003'
    //	 example 4: x = date('Y m d', (new Date()).getTime()/1000);
    //	 example 4: (x+'').length == 10 // 2009 01 09
    //	 returns 4: true
    //	 example 5: date('W', 1104534000);
    //	 returns 5: '53'
    //	 example 6: date('B t', 1104534000);
    //	 returns 6: '999 31'
    //	 example 7: date('W U', 1293750000.82); // 2010-12-31
    //	 returns 7: '52 1293750000'
    //	 example 8: date('W', 1293836400); // 2011-01-01
    //	 returns 8: '52'
    //	 example 9: date('W Y-m-d', 1293974054); // 2011-01-02
    //	 returns 9: '52 2011-01-02'

    var that = this;
    var jsdate, f;
    // Keep this here (works, but for code commented-out below for file size reasons)
    // var tal= [];
    var txt_words = [
        'Sun', 'Mon', 'Tues', 'Wednes', 'Thurs', 'Fri', 'Satur',
        'January', 'February', 'March', 'April', 'May', 'June',
        'July', 'August', 'September', 'October', 'November', 'December'
    ];
    // trailing backslash -> (dropped)
    // a backslash followed by any character (including backslash) -> the character
    // empty string -> empty string
    var formatChr = /\\?(.?)/gi;
    var formatChrCb = function(t, s) {
        return f[t] ? f[t]() : s;
    };
    var _pad = function(n, c) {
        n = String(n);
        while (n.length < c) {
            n = '0' + n;
        }
        return n;
    };
    f = {
        // Day
        d: function() {
            // Day of month w/leading 0; 01..31
            return _pad(f.j(), 2);
        },
        D: function() {
            // Shorthand day name; Mon...Sun
            return f.l()
                .slice(0, 3);
        },
        j: function() {
            // Day of month; 1..31
            return jsdate.getDate();
        },
        l: function() {
            // Full day name; Monday...Sunday
            return txt_words[f.w()] + 'day';
        },
        N: function() {
            // ISO-8601 day of week; 1[Mon]..7[Sun]
            return f.w() || 7;
        },
        S: function() {
            // Ordinal suffix for day of month; st, nd, rd, th
            var j = f.j();
            var i = j % 10;
            if (i <= 3 && parseInt((j % 100) / 10, 10) == 1) {
                i = 0;
            }
            return ['st', 'nd', 'rd'][i - 1] || 'th';
        },
        w: function() {
            // Day of week; 0[Sun]..6[Sat]
            return jsdate.getDay();
        },
        z: function() {
            // Day of year; 0..365
            var a = new Date(f.Y(), f.n() - 1, f.j());
            var b = new Date(f.Y(), 0, 1);
            return Math.round((a - b) / 864e5);
        },

        // Week
        W: function() {
            // ISO-8601 week number
            var a = new Date(f.Y(), f.n() - 1, f.j() - f.N() + 3);
            var b = new Date(a.getFullYear(), 0, 4);
            return _pad(1 + Math.round((a - b) / 864e5 / 7), 2);
        },

        // Month
        F: function() {
            // Full month name; January...December
            return txt_words[6 + f.n()];
        },
        m: function() {
            // Month w/leading 0; 01...12
            return _pad(f.n(), 2);
        },
        M: function() {
            // Shorthand month name; Jan...Dec
            return f.F()
                .slice(0, 3);
        },
        n: function() {
            // Month; 1...12
            return jsdate.getMonth() + 1;
        },
        t: function() {
            // Days in month; 28...31
            return (new Date(f.Y(), f.n(), 0))
                .getDate();
        },

        // Year
        L: function() {
            // Is leap year?; 0 or 1
            var j = f.Y();
            return j % 4 === 0 & j % 100 !== 0 | j % 400 === 0;
        },
        o: function() {
            // ISO-8601 year
            var n = f.n();
            var W = f.W();
            var Y = f.Y();
            return Y + (n === 12 && W < 9 ? 1 : n === 1 && W > 9 ? -1 : 0);
        },
        Y: function() {
            // Full year; e.g. 1980...2010
            return jsdate.getFullYear();
        },
        y: function() {
            // Last two digits of year; 00...99
            return f.Y()
                .toString()
                .slice(-2);
        },

        // Time
        a: function() {
            // am or pm
            return jsdate.getHours() > 11 ? 'pm' : 'am';
        },
        A: function() {
            // AM or PM
            return f.a()
                .toUpperCase();
        },
        B: function() {
            // Swatch Internet time; 000..999
            var H = jsdate.getUTCHours() * 36e2;
            // Hours
            var i = jsdate.getUTCMinutes() * 60;
            // Minutes
            // Seconds
            var s = jsdate.getUTCSeconds();
            return _pad(Math.floor((H + i + s + 36e2) / 86.4) % 1e3, 3);
        },
        g: function() {
            // 12-Hours; 1..12
            return f.G() % 12 || 12;
        },
        G: function() {
            // 24-Hours; 0..23
            return jsdate.getHours();
        },
        h: function() {
            // 12-Hours w/leading 0; 01..12
            return _pad(f.g(), 2);
        },
        H: function() {
            // 24-Hours w/leading 0; 00..23
            return _pad(f.G(), 2);
        },
        i: function() {
            // Minutes w/leading 0; 00..59
            return _pad(jsdate.getMinutes(), 2);
        },
        s: function() {
            // Seconds w/leading 0; 00..59
            return _pad(jsdate.getSeconds(), 2);
        },
        u: function() {
            // Microseconds; 000000-999000
            return _pad(jsdate.getMilliseconds() * 1000, 6);
        },

        // Timezone
        e: function() {
            // Timezone identifier; e.g. Atlantic/Azores, ...
            // The following works, but requires inclusion of the very large
            // timezone_abbreviations_list() function.
            /*				return that.date_default_timezone_get();
             */
            throw 'Not supported (see source code of date() for timezone on how to add support)';
        },
        I: function() {
            // DST observed?; 0 or 1
            // Compares Jan 1 minus Jan 1 UTC to Jul 1 minus Jul 1 UTC.
            // If they are not equal, then DST is observed.
            var a = new Date(f.Y(), 0);
            // Jan 1
            var c = Date.UTC(f.Y(), 0);
            // Jan 1 UTC
            var b = new Date(f.Y(), 6);
            // Jul 1
            // Jul 1 UTC
            var d = Date.UTC(f.Y(), 6);
            return ((a - c) !== (b - d)) ? 1 : 0;
        },
        O: function() {
            // Difference to GMT in hour format; e.g. +0200
            var tzo = jsdate.getTimezoneOffset();
            var a = Math.abs(tzo);
            return (tzo > 0 ? '-' : '+') + _pad(Math.floor(a / 60) * 100 + a % 60, 4);
        },
        P: function() {
            // Difference to GMT w/colon; e.g. +02:00
            var O = f.O();
            return (O.substr(0, 3) + ':' + O.substr(3, 2));
        },
        T: function() {
            // Timezone abbreviation; e.g. EST, MDT, ...
            // The following works, but requires inclusion of the very
            // large timezone_abbreviations_list() function.
            /*				var abbr, i, os, _default;
            if (!tal.length) {
            tal = that.timezone_abbreviations_list();
            }
            if (that.php_js && that.php_js.default_timezone) {
            _default = that.php_js.default_timezone;
            for (abbr in tal) {
            	for (i = 0; i < tal[abbr].length; i++) {
            	if (tal[abbr][i].timezone_id === _default) {
            		return abbr.toUpperCase();
            	}
            	}
            }
            }
            for (abbr in tal) {
            for (i = 0; i < tal[abbr].length; i++) {
            	os = -jsdate.getTimezoneOffset() * 60;
            	if (tal[abbr][i].offset === os) {
            	return abbr.toUpperCase();
            	}
            }
            }
            */
            return 'UTC';
        },
        Z: function() {
            // Timezone offset in seconds (-43200...50400)
            return -jsdate.getTimezoneOffset() * 60;
        },

        // Full Date/Time
        c: function() {
            // ISO-8601 date.
            return 'Y-m-d\\TH:i:sP'.replace(formatChr, formatChrCb);
        },
        r: function() {
            // RFC 2822
            return 'D, d M Y H:i:s O'.replace(formatChr, formatChrCb);
        },
        U: function() {
            // Seconds since UNIX epoch
            return jsdate / 1000 | 0;
        }
    };

    this.date = function(format, timestamp) {
        that = this;
        jsdate = (timestamp === undefined ? new Date() : // Not provided
            (timestamp instanceof Date) ? new Date(timestamp) : // JS Date()
            new Date(timestamp * 1000) // UNIX timestamp (auto-convert to int)
        );
        return format.replace(formatChr, formatChrCb);
    };
    return this.date(format, timestamp);
}